package com.ctgu.tengyun.handler;


import com.ctgu.tengyun.bean.errorcode.ResultConstant;
import com.ctgu.tengyun.bean.response.BaseResponse;
import com.ctgu.tengyun.bean.response.RespGenerator;
import com.ctgu.tengyun.exception.*;
import org.apache.commons.httpclient.HttpStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.converter.HttpMessageConversionException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@ControllerAdvice
public class AdviceExceptionHandler {

    private static final Logger logger = LoggerFactory.getLogger(AdviceExceptionHandler.class);

    public static final String COMMON_RESP_FIELD = "response";

    @ExceptionHandler(Exception.class)
    public @ResponseBody
    Object errorResponse(Exception ex, HttpServletRequest request, HttpServletResponse response) {

        BaseResponse baseResponse = new BaseResponse();

        if (ex instanceof ServletException) {
            response.setStatus(HttpStatus.SC_UNPROCESSABLE_ENTITY);
            baseResponse = RespGenerator.getUnprocessableErrResp(ex.getMessage());
            logger.warn(ex.getMessage(), ex);
        } else if (ex instanceof UnAuthorizedException) {
            response.setStatus(HttpStatus.SC_UNAUTHORIZED);
            baseResponse = RespGenerator.getUnauthErrResp(ex.getMessage());
            logger.warn(ex.getMessage(), ex);
        } else if (ex instanceof ResourceNotFoundException) {
            String reason = ((ResourceNotFoundException) ex).getReason();
            baseResponse = RespGenerator.getNotFoundErrResp(reason);
            response.setStatus(HttpStatus.SC_OK);
            logger.warn(ex.getMessage(), ex);
        } else if (ex instanceof ErrorCodeException) {
            ErrorCodeInterface errorCodeInterface = ((ErrorCodeException) ex).getErrorCodeInterface();
            baseResponse.setErrorCode(errorCodeInterface.getErrorCode());
            baseResponse.setErrorMessage(errorCodeInterface.getHintMessage());
            response.setStatus(HttpStatus.SC_OK);
            logger.info(ex.getMessage(), ex);
        } else if (ex instanceof ForbiddenException) {
            response.setStatus(HttpStatus.SC_FORBIDDEN);
            String reason = ((ForbiddenException) ex).getReason();
            baseResponse = RespGenerator.getForbiddenErrResp(reason);
            logger.warn(ex.getMessage(), ex);
        } else if (ex instanceof RequestValidateException) {
            response.setStatus(HttpStatus.SC_UNPROCESSABLE_ENTITY);
            String reason = ((RequestValidateException) ex).getReason();
            baseResponse = RespGenerator.getUnprocessableErrResp(reason);
            logger.warn(ex.getMessage(), ex);
        } else if (ex instanceof ConvertException) {
            response.setStatus(HttpStatus.SC_UNPROCESSABLE_ENTITY);
            String reason = ((ConvertException) ex).getReason();
            baseResponse = RespGenerator.getUnprocessableErrResp(reason);
            logger.warn(ex.getMessage(), ex);
        } else if (ex instanceof HttpMessageConversionException) {
            response.setStatus(HttpStatus.SC_UNPROCESSABLE_ENTITY);
            String reason = ex.getMessage();
            baseResponse = RespGenerator.getUnprocessableErrResp(reason);
            logger.warn(ex.getMessage(), ex);
        } else if (ex instanceof ConcurrentUpdateException) {
            response.setStatus(HttpStatus.SC_INTERNAL_SERVER_ERROR);
            String reason = ((ConcurrentUpdateException) ex).getReason();
            baseResponse = RespGenerator.getConcurrentUpdateErrResp(reason);
            logger.warn(ex.getMessage(), ex);
        } else if (ex instanceof ExternalSystemException) {
            response.setStatus(HttpStatus.SC_INTERNAL_SERVER_ERROR);
            String reason = ((ExternalSystemException) ex).getReason();
            baseResponse = RespGenerator.getExternalSysErrResp(reason);
            logger.error(ex.getMessage(), ex);
        } else {
            baseResponse.setErrorCode(ResultConstant.SC_INTERNAL_SERVER_ERR_CODE);
            baseResponse.setErrorMessage(ResultConstant.SC_INTERNAL_SERVER_ERR_DATA);
            response.setStatus(HttpStatus.SC_INTERNAL_SERVER_ERROR);
            logger.error(ex.getMessage(), ex);
        }

        return baseResponse;
    }
}
